package com.wmx.thread.concurrent;

import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

/**********************************
 * @author wmx
 * @date 2019/8/26 9:11
 * @description:
 * @version 1.0
 ************************************/
@Slf4j
public class SemaphoreExample {
    private final static int threadCount = 200;

    public static void main(String[] args) {
       // doSemaphoreOne();
        semaphoreCommunication();
    }
    //控制同时访问某个特定资源的操作数量
    private static void doSemaphoreOne(){
        ExecutorService executorService = Executors.newFixedThreadPool(20);
        //1、信号量为1时 相当于普通的锁  信号量大于1时 共享锁
        Semaphore semaphore = new Semaphore(1);
        for (int i = 0; i < threadCount; i++) {
            int tempCount = i;
            executorService.execute(()->{
                try {
                    semaphore.acquire();
                    TimeUnit.SECONDS.sleep(1);
                    log.info("{}"+tempCount);
                    semaphore.release();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {

                }
            });
        }
        executorService.shutdown();
    }

    //线程通信信号
    public static void semaphoreCommunication(){
        Semaphore semaphore = new Semaphore(1,true);

        SemaphoreCommunication semaphoreCommunication = new SemaphoreCommunication(semaphore,"semaphoreCommunication",20);

        new Thread(semaphoreCommunication).start();
        new Thread(semaphoreCommunication).start();
        new Thread(semaphoreCommunication).start();
        new Thread(semaphoreCommunication).start();

    }

}
@Slf4j
@AllArgsConstructor
class SemaphoreCommunication  implements  Runnable{
    private Semaphore semaphore;
    private String name ;
    private volatile int count;
    @Override
    public void run() {

            try {
                while (count > 0){
                    semaphore.acquire();
                    TimeUnit.SECONDS.sleep(0);
                    log.info("{"+Thread.currentThread().getName()+"}"+"======{"+name+count+"}");
                    count--;
                    semaphore.release();
                }

            } catch (InterruptedException e) {
                e.printStackTrace();
            }

    }
}